package dtd.PHS.VND_ExchangeRate.ui;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;
import dtd.PHS.VND_ExchangeRate.PreviewSMS;
import dtd.PHS.VND_ExchangeRate.R;
import dtd.PHS.VND_ExchangeRate.data.DataProvider;
import dtd.PHS.VND_ExchangeRate.data.ListRates;
import dtd.PHS.VND_ExchangeRate.data.RateItem;
import dtd.PHS.VND_ExchangeRate.utils.Helpers;

public class CalculatorView extends RequestableFrameLayout {
	private static final int MAX_SPINNERS_COUNT = 2;
	public static final String CURRENCIES_INFO = "CURRENCIES_INFO";
	private Activity hostedActivity;

	public CalculatorView(Activity activity) {
		super(activity);
		this.hostedActivity = activity;
	}


	@Override
	public void createViews() {
	    Helpers.inflateView(hostedActivity,R.layout.calculator_act,this);
	    main_frames = (FrameLayout) findViewById(R.id.main_frames);
	    initEditTexts();
	    initSpinners();
	    initButtons();
	}
	
	private void initButtons() {
		Button btReset = (Button) findViewById(R.id.btReset);
		btReset.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				for(EditText et : etMainAmount) {
					et.setText("");
				}
			}
		});
		
		Button btShare = (Button) findViewById(R.id.btShare);
		btShare.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Bundle mapCurr2Value = getAllCurrenciesInfo();
				Intent i = new Intent(hostedActivity, PreviewSMS.class);
				i.putExtra( CURRENCIES_INFO, mapCurr2Value);
				hostedActivity.startActivity(i);
			}
		});
	}
	
	protected Bundle getAllCurrenciesInfo() {
		Bundle info  = new Bundle();
		for(EditText et : etMainAmount) {
			String currency = mapET2Currency.get(et);
			info.putString(currency,et.getText().toString().trim());
		}
		return info;
	}
	
	private Spinner[] spinners;
	private ArrayAdapter<String>[] adapters;
	private ArrayList<String> allCurrenciesExceptVND;
	private static final int[] SPINNERS_ID = {R.id.spinnerEdit01,R.id.spinnerEdit02};
	private void initSpinners() {
		spinners = new Spinner[2];
		adapters = new ArrayAdapter[MAX_SPINNERS_COUNT];
		allCurrenciesExceptVND = DataProvider.getInstance().getAllCurrenciesExceptVND();		
		for(int i = 0 ; i < MAX_SPINNERS_COUNT ; i++) {
			createSpinner(i);
		}
	}

	private void createSpinner(int i) {
		View v = findViewById(SPINNERS_ID[i]);
		spinners[i] = (Spinner) v.findViewById(R.id.spCurrencies);
		int id = i + MAIN_CURRENCIES.length;
		etMainAmount[id] = (EditText) v.findViewById(R.id.etSpinnerAmount);
		etMainAmount[id].addTextChangedListener(new MyTextWatcher(etMainAmount[id]));
		adapters[i] = new ArrayAdapter<String>(hostedActivity, android.R.layout.simple_spinner_item, allCurrenciesExceptVND);
		adapters[i].setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinners[i].setAdapter(adapters[i]);
		spinners[i].setSelection(getLastSelectedSpinnerCurrency(i));
		String currency = (String) spinners[i].getSelectedItem();
		mapET2Currency.put(etMainAmount[id],currency);
		spinners[i].setOnItemSelectedListener(new OnSpinnerItemSelected(id));
	}

	private int getLastSelectedSpinnerCurrency(int i) {
		try {
			String s = Helpers.getPreference(Helpers.PREF_LAST_CHOOSEN_SPINNER[i]);
			return Integer.parseInt(s);
		} catch (Exception e) {
			return 0;
		}
	}

	private static final int VND_INDEX = 0;
	static final private String[] MAIN_CURRENCIES = {"VND","USD","EUR"};
	static final private int[] MAIN_CURRENCIES_ID = {R.id.lineVND,R.id.lineUSD,R.id.lineEUR};
	private EditText[] etMainAmount;
	private void initEditTexts() { etMainAmount  = new EditText[MAIN_CURRENCIES.length + SPINNERS_ID.length];
		for(int i = 0 ; i < MAIN_CURRENCIES.length ; i++) {
			View v = findViewById(MAIN_CURRENCIES_ID[i]);
			TextView tvTitle = (TextView) v.findViewById(R.id.tvTitle);
			tvTitle.setText(MAIN_CURRENCIES[i]);
			etMainAmount[i] = (EditText)v.findViewById(R.id.etAmount);
			etMainAmount[i].addTextChangedListener(new MyTextWatcher(etMainAmount[i]));
			mapET2Currency.put( etMainAmount[i], MAIN_CURRENCIES[i]);
		}
	}

	@Override
	public void onGetDataCompleted(Object data) {
		if ( data instanceof ListRates) {
			//Recalculate Rate
			long amount = getVNDAmount();
			if ( amount != 0 )			
				etMainAmount[VND_INDEX].setText(String.valueOf(amount));
			else {
				for(EditText et : etMainAmount) {
					et.setText("");
				}
			}
			//TODO: show a waiting progress for 1 second
		}
	}

	private long getVNDAmount() {
		long amount = 0;
		String str = etMainAmount[VND_INDEX].getText().toString();
		if ( str == null || str.length() == 0 ) {
		} else {
			try {
				amount = Long.parseLong(Helpers.getRidOfComma(str));
			} catch (Exception e) {
				amount = 0;
			}
		}
		return amount;
	}

	@Override
	public void onGetDataError(Exception e) {
		// TODO Auto-generated method stub
		
	}
	
	public class OnSpinnerItemSelected implements OnItemSelectedListener {

		private int id;

		public OnSpinnerItemSelected(int i) {
			this.id = i;
		}

		@Override
		public void onItemSelected(AdapterView<?> arg0, View arg1, int position,
				long arg3) {
			String currencyName = allCurrenciesExceptVND.get(position);
			mapET2Currency.put(etMainAmount[id], currencyName);
			forceUpdateEditText(etMainAmount[id]);
			Helpers.setPreference(Helpers.PREF_LAST_CHOOSEN_SPINNER[id-MAIN_CURRENCIES.length], ""+position);
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
		}

	}
	
	private void forceUpdateEditText(EditText et) {
		if (etMainAmount[VND_INDEX].getText().toString().equals("")) return;
		String amountVNDString = Helpers.getRidOfComma(etMainAmount[VND_INDEX].getText().toString());
		long amountVND = Long.parseLong(amountVNDString);
		long amountExchange = RateItem.changeFromTo("VND", mapET2Currency.get(et), amountVND);
		et.setText(Helpers.formatCurrency(Long.toString(amountExchange)));
	
	}
	private HashMap<EditText, String> mapET2Currency = new HashMap<EditText, String>();
	
	public class MyTextWatcher implements TextWatcher {

		private EditText toWatchEditText;
		private int oldPos;
		private String oldText;

		public MyTextWatcher(EditText editText) {
			toWatchEditText = editText;
		}

		@Override
		public void afterTextChanged(Editable s) {
			if ( this.toWatchEditText.findFocus() != null) {
				String amount = Helpers.getRidOfComma(s.toString());
				if ( Helpers.isValidLong(amount)) {
					updateEditTexts( amount );
				}
			}
		}

		private void updateEditTexts(String amount) {
			for(EditText et : etMainAmount) {
				if ( et.findFocus() == null) {
					long exchangeAmount = RateItem.changeFromTo(
							mapET2Currency.get(toWatchEditText),
							mapET2Currency.get(et),
							Long.parseLong(amount)							
					);
					et.setText(Helpers.formatCurrency(""+exchangeAmount));
				} else {
					String afterString = Helpers.formatCurrency(amount);
					if ( ! afterString.equals(toWatchEditText.getText().toString()) ) {
						int newCursorPosition = Helpers.newCursorPosition(this.oldPos,this.oldText,afterString);
						toWatchEditText.setText(afterString);
						Editable etext = toWatchEditText.getText(); 
						Selection.setSelection(etext, newCursorPosition);
					}
				}
			}
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,	int after) {
			this.oldText = s.toString();
			this.oldPos = Selection.getSelectionStart(toWatchEditText.getText());
		}

		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			// nothing

		}

	}



}
